 aR  w - mP9      h	 o     nSystem-wide%SET (supportsEmsWindows, 0)
$NOLIST

    NAME ScreenDependencies

; This is S40Scrn.Asm.

; This is the only module that has screen dependencies amongst the
; 640x400 screen displays of the Hercules/AT&T style architectures


; If screenType = 0; then this is for a Hercules display.
; If screenType = 1; then this is for a GRiD286 (AT&T mode) display.
; If screenType = 2; then this is for a Toshiba 3100 display.

; NOTE: The AT&T and Toshiba displays are almost identical


CGROUP GROUP CODE

EXTRN	scrOrientation: BYTE

PUBLIC screenSeg, bitsPerPixel

PUBLIC ScrSetScreenMode
PUBLIC ScrScreenInfo

%IF (%supportsEmsWindows EQ 1) THEN (
PUBLIC emsBase
) FI

gridCaseAspect EQU 100 ; aspect of 100 will bring out bug in GPaint
herculesAspect EQU 145
toshibaAspect  EQU 120

%IF (%screenType EQ 0) THEN (
screenSeg    EQU 0B000H
screenWidth  EQU 720
screenHeight EQU 348
screenAspect EQU 145
bitsPerPixel EQU 1
) FI

%IF (%screenType EQ 1) THEN (
screenSeg    EQU 0B800H
screenWidth  EQU 640
screenHeight EQU 400
screenAspect EQU 100
bitsPerPixel EQU 1
) FI

%IF (%screenType EQ 2) THEN (
screenSeg    EQU 0B800H
screenWidth  EQU 640
screenHeight EQU 400
screenAspect EQU 120
bitsPerPixel EQU 1
) FI


CODE SEGMENT PUBLIC 'CODE'
  ASSUME CS:CGROUP


%IF (%supportsEmsWindows EQ 1) THEN (
emsBase DW 0FFFFH          ; Init to -1 to flag that it isn't set yet
) FI
$EJECT

;   ScrSetScreenMode: PROCEDURE CLEAN;
;
;  This routine will set the screen to Hercules Graphics mode
;

%IF (%screenType EQ 0) THEN (
gTable    DB 35h, 2dh, 2eh, 07h, 5bh, 02h, 57h, 57h, 02h, 03h, 00h, 00h
) FI

ScrSetScreenMode PROC FAR
  PUSH DS
  PUSH BP

%IF (%supportsEmsWindows EQ 1) THEN (
  CMP  CS:emsBase, 0FFFFH
  JNE  SetScrModeEmsBaseSet

  INT  71H                    ; Call to Cp Module
  DB   58H                    ; EmsStartAddress
  MOV  CS:emsBase, AX

SetScrModeEmsBaseSet:
) FI

%IF (%screenType EQ 1) THEN (
  MOV  AX, 40H
  INT  10H
) FI

%IF (%screenType EQ 2) THEN (
  MOV  AX, 74H
  INT  10H
) FI

%IF (%screenType EQ 0) THEN (
; Clear direction for LODSB & SETW below
  CLD

; Allow setting of graphics mode
  MOV  AL, 1
  MOV  DX, 3BFH     ; Hercules Configuration Switch
  OUT  DX, AL

; Change mode to graphics but without screen display enabled
  MOV  AL, 2
  MOV  DX, 3B8H
  OUT  DX, AL

; Initialize the 6845
  MOV  AX, CS
  MOV  DS, AX
  MOV  SI, OFFSET CGROUP:gTable

  MOV  DX, 3B4H
  MOV  CX, 12
; CLD               ; (Done above)
  XOR  AH, AH

Parms:
  MOV  AL, AH
  OUT  DX, AL
  INC  DX
  LODSB
  OUT  DX, AL
  INC  AH           ; next value
  DEC  DX
  LOOP Parms

; Clear the display buffer
  MOV  CX, 04000H
  MOV  AX, screenSeg
  MOV  ES, AX
  XOR  DI, DI
  XOR  AX, AX
; CLD               ; (Done above)
  REP  STOSW

; Turn screen on in graphics mode, page 0
  MOV  DX, 3B8H
  MOV  AL, 10
  OUT  DX, AL
) FI

  POP   BP
  POP   DS
  RET
ScrSetScreenMode ENDP  
$EJECT

;    ScrScreenInfo : PROCEDURE (pInfo) CLEAN;
;      DCL pInfo     PTR;
;      DCL info      BASED pInfo  ScreenInfoType;
;
;    This will return information about screen size, etc.

; NOTE: The yAspect value has to be divisible down to a small fraction to
;       be usable by GPlan2 and GPaint.  Values that are known to work are
;       100 (obviously), 140 and 120.  The smallest known value to work on
;       a 640xnnn display is 105.  DO NOT USE 100 unless GPaint is rereleased.
; AND...Do not ever use a yAspect value of 100.  This is because of a bug in
;       GPaint.  It assumes that the machine that it is running on is a
;       Compass (w/ screen mode = grid mode) whenever aspect is 100.
; BUT...Now that this is used for something beyond InteGRiD, the above doesn't
;       matter and the correct aspect ratio (100 vs 105) should be used.

ScreenInfoType STRUC
  xPixels     DW ?
  yPixels     DW ?
  screenAddr  DW ?
  yAspect     DW ?
  bitsPerPel  DB ?
ScreenInfoType ENDS

screenInfo   EQU ES:[DI]
pScreenInfo  EQU DWORD PTR [BP+6]

ScrScreenInfo PROC FAR
  PUSH BP
  MOV  BP, SP

  LES  DI, pScreenInfo

	MOV	AX, screenWidth
	MOV	BX, screenHeight
	TEST	CS:scrOrientation, 1
	JZ	ScrIsNorthOrSouth

ScrIsWestOrEast:
	XCHG	AX, BX

ScrIsNorthOrSouth:
	MOV	screenInfo.xPixels, AX
	MOV	screenInfo.yPixels, BX
  MOV  screenInfo.screenAddr, screenSeg
  MOV  screenInfo.yAspect, screenAspect
  MOV  screenInfo.bitsPerPel, bitsPerPixel

  POP  BP
  RET  4
ScrScreenInfo ENDP

PURGE screenInfo
PURGE pScreenInfo
PURGE ScreenInfoType
PURGE xPixels
PURGE yPixels
PURGE screenAddr
PURGE bitsPerPel
PURGE yAspect


CODE ENDS

    END
